package com.ssy.lingxi.platform.manage.serviceimpl;

import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.model.vo.SelectVO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.platform.manage.api.model.dto.unit.UnitDTO;
import com.ssy.lingxi.platform.manage.entity.base.Unit;
import com.ssy.lingxi.platform.manage.repository.UnitRepository;
import com.ssy.lingxi.platform.manage.service.IUnitService;
import com.ssy.lingxi.product.api.feign.ICommodityFeign;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 单位实现类
 * @author jw.chen
 * @version 2.0.0
 * @date 2020/6/22
 */
@Service
public class UnitServiceImpl implements IUnitService {

    @Autowired
    private UnitRepository unitRepository;

    @Autowired
    private IRedisStringUtils redisStringUtils;

    @Autowired
    private ICommodityFeign commodityFeign;

    /**
     * 查询单位列表
     * @return Page<Attribute>
     */
    @Override
    public Page<Unit> getUnitList(PageVO pageVO, String name){
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").descending());
        if(StringUtils.isNotEmpty(name)){
            return unitRepository.findByNameContaining(name, page);
        }else{
            return unitRepository.findAll(page);
        }
    }

    /**
     * 查询单位
     * @return id
     */
    @Override
    public Unit getUnit(Long id){
        return unitRepository.findById(id).orElse(null);
    }

    /**
     * 添加/修改单位
     */
    @Override
    public String saveOrUpdateUnit(UnitDTO unitRequest){
        Long id = unitRequest.getId();
        String name = unitRequest.getName();
        String englishShortName = unitRequest.getEnglishShortName();

        Unit unit = new Unit();
        //判断是新增还是修改
        if(id != null && id > 0){
            Unit current_unit = unitRepository.findById(id).orElse(null);
            if(current_unit == null){
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_NOT_EXIST);
            }
            List<Unit> currentUnitList = unitRepository.findByNameAndIdNot(name, id);
            if(!currentUnitList.isEmpty()){
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_NAME_EXIST);
            }

            List<Unit> currentENUnitList = unitRepository.findByEnglishShortNameAndIdNot(englishShortName, id);
            if(!currentENUnitList.isEmpty()){
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_EN_NAME_EXIST);
            }
            //修改的时候状态不变
            unit.setId(current_unit.getId());
            unit.setStatus(current_unit.getStatus());
        }else{
            List<Unit> currentUnitList = unitRepository.findByName(name);
            if(!currentUnitList.isEmpty()){
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_NAME_EXIST);
            }

            List<Unit> currentENUnitList = unitRepository.findByEnglishShortName(englishShortName);
            if(!currentENUnitList.isEmpty()){
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_EN_NAME_EXIST);
            }
            unit.setStatus(true);
        }
        //数据库持久化对象
        unit.setEnglishShortName(englishShortName);
        unit.setName(name);
        unitRepository.saveAndFlush(unit);
        //将单位信息缓存到redis
        redisStringUtils.hSet(Constants.REDIS_KEY_UNIT, String.valueOf(unit.getId()), unit.getName() + Constants.SPLIT_STR + unit.getEnglishShortName(), Constants.REDIS_PLATFORM_MANAGE_INDEX);
        return ResponseCode.SUCCESS.getMessage();
    }

    /**
     * 删除单位
     */
    @Override
    public String deleteUnit(Long id) {
        //验证数据库中是否存在该数据
        Unit unit = unitRepository.findById(id).orElse(null);
        if(unit != null){
            Boolean status = unit.getStatus();
            if(status){
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_NOT_DELETE);
            }
            //检查是否有商品还在使用，如在使用，不能删除
            Wrapper<Boolean> commodityUseUnit = commodityFeign.getCommodityUseUnit(id);
            if(ResponseCode.SUCCESS.getCode() == commodityUseUnit.getCode()){
                Boolean data = commodityUseUnit.getData();
                if(data){
                    throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_COMMODITY_USE_NOT_DELETE);
                }else{
                    //从redis删除停用的单位
                    redisStringUtils.hDel(Constants.REDIS_KEY_UNIT, String.valueOf(unit.getId()), Constants.REDIS_PLATFORM_MANAGE_INDEX);
                    //从数据库中删除
                    unitRepository.deleteById(id);
                    return ResponseCode.SUCCESS.getMessage();
                }
            }else{
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_COMMODITY_CHECK);
            }
        }else{
            throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_NOT_EXIST);
        }
    }

    /**
     * 启用/停用属性
     */
    @Override
    public String updateUnitStatus(long id, Boolean status){
        //验证数据库中是否存在该数据
        Unit unit = unitRepository.findById(id).orElse(null);
        if(unit != null){
            if(!status){
                //检查是否有商品还在使用，如在使用，不能停用
                Wrapper<Boolean> commodityUseUnit = commodityFeign.getCommodityUseUnit(id);
                if(ResponseCode.SUCCESS.getCode() == commodityUseUnit.getCode()){
                    Boolean data = commodityUseUnit.getData();
                    if(data){
                        throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_COMMODITY_USE_NOT_DISABLE);
                    }else{
                        //从redis删除停用的单位
                        redisStringUtils.hDel(Constants.REDIS_KEY_UNIT, String.valueOf(unit.getId()), Constants.REDIS_PLATFORM_MANAGE_INDEX);
                    }
                }else{
                    throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_COMMODITY_CHECK);
                }
            }else{
                //将单位信息缓存到redis
                redisStringUtils.hSet(Constants.REDIS_KEY_UNIT, String.valueOf(unit.getId()), unit.getName() + Constants.SPLIT_STR + unit.getEnglishShortName(), Constants.REDIS_PLATFORM_MANAGE_INDEX);
            }
            //持久化数据
            unit.setStatus(status);
            unitRepository.saveAndFlush(unit);
            return ResponseCode.SUCCESS.getMessage();
        }else{
            throw new BusinessException(ResponseCode.PLATFORM_MANAGE_UNIT_NOT_EXIST);
        }
    }

    /**
     * 查询中文单位下拉框
     * @param name 单位名称
     */
    @Override
    public List<SelectVO> getSelectCNUnit(String name) {
        //根据条件查询
        Pageable pageable = PageRequest.of(0, Constants.SELECT_COUNT);
        Page<Unit> page = unitRepository.findByNameContainingAndStatusOrderByIdDesc(name, true, pageable);
        //转换SelectVO实体
        return page.getContent().stream().map(customerCategory -> {
            SelectVO selectVO = new SelectVO();
            selectVO.setId(customerCategory.getId());
            selectVO.setName(customerCategory.getName());
            return selectVO;
        }).collect(Collectors.toList());
    }

    /**
     * 查询英文单位下拉框
     * @param name 单位名称
     */
    @Override
    public List<SelectVO> getSelectENUnit(String name) {
        //根据条件查询
        Pageable pageable = PageRequest.of(0, Constants.SELECT_COUNT);
        Page<Unit> page = unitRepository.findByNameContainingAndStatusOrderByIdDesc(name, true, pageable);
        //转换SelectVO实体
        return page.getContent().stream().map(customerCategory -> {
            SelectVO selectVO = new SelectVO();
            selectVO.setId(customerCategory.getId());
            selectVO.setName(customerCategory.getEnglishShortName());
            return selectVO;
        }).collect(Collectors.toList());
    }

    /**
     * 单位缓存到redis
     */
    @Async
    @Override
    public void initToRedis() {
        redisStringUtils.del(Constants.REDIS_KEY_UNIT, Constants.REDIS_PLATFORM_MANAGE_INDEX);
        List<Unit> unitList = unitRepository.findByStatus(true);
        if(unitList != null && !unitList.isEmpty()){
            Map<String, String> map = new HashMap<>();
            unitList.forEach(unit -> map.put(String.valueOf(unit.getId()), unit.getName() + Constants.SPLIT_STR + unit.getEnglishShortName()));
            redisStringUtils.hMSet(Constants.REDIS_KEY_UNIT, map, Constants.REDIS_PLATFORM_MANAGE_INDEX);
        }
    }
}

